This sample shows how to communicate with a USB CDC (Communications Device Class) device and sends and receives data through serial ports, such as a USB serial converter cable. The sample demonstrates the use of the Windows.Devices.Usb namespace.
To run this sample you need:
- USB to RS-232 serial adapters which are compatible with USB CDC standard protocol. For scenario 4-loopback, you need two adapters.
- A serial device that can send data.
- A null-model cable.
The sample demonstrates these key scenarios:
| Windows runtime class | Description |
|---|---|
| DeviceListEntry |
This class stores DeviceInformation objects associated with each device, dynamically detected by the DeviceWatcher object. This class is used by the UI to display device-specific information. |
| DeviceList |
The singleton class creates a DeviceWatcher object that finds all devices that use Winusb.sys as the device driver. The list of detected devices are shown on the UI list. Each device in the list is a DeviceListEntry object. |
| CdcAcmInitialize |
This class implements methods that opens the device (gets the UsbDevice object) selected by the user. After that, it instantiates the UsbSerialPort class that represents a virtual serial port. When the user clicks the Initialize button, based on the properties selected by the user such as DTERate, ParityType, and so on, it opens the serial port for communication. All subsequent transfers are sent to or received from that port. |
| CdcAcmRead |
The class implements methods that read from the bulk IN endpoint of the USB CDC device. The user can request a specific number of bytes to read, or can get continuous input of data read from the endpoint. Data is read by using the DataReader object. |
| CdcAcmWrite |
The class implements methods that write to the bulk OUT endpoint of the USB CDC device. The user can write a text string or contents of a binary file. Data is written by using the DataWriter object. |
| CdcAcmLoopback |
The class implements methods that opens two devices. The user writes data to an endpoint of one device and reads that data from the other device. When the page loads for this scenario, the previously selected device is removed from DeviceList. The detected devices are added to both UI lists. When the user initializes devices, the serial port associated with the first device is opened for writing. The serial port for the second device is opened for reading. Data is read from the first bulk IN pipe as it arrives from the first bulk OUT endpoint of the first device. Data is read and written by using DataReader and DataWriter objects. |
| UsbSerialPort |
This class implements a virtual COM port that exposes the underlying UsbDevice object as a serial device. It implements methods to perform these tasks:
|
App manifest package
The sample adds the DeviceCapability element in the Package.appxmanifest file. Device information includes the device's vendor/product Ids and device class information.
To use the sample, add vendor/product id information for your USB to serial adapter to the Package.appxmanifest file. You can obtain that information from the Device Manager properties (see Hardware Id).
<Capabilities>
<m2:DeviceCapability Name="usb">
<m2:Device Id="vidpid:056E 5003">
<m2:Function Type="classId:ff * *" />
</m2:Device>
<m2:Device Id="vidpid:056E 5004">
<m2:Function Type="classId:ff * *" />
</m2:Device>
</m2:DeviceCapability>
</Capabilities>
Related topics
Related technologies
Windows.Devices.UsbProvides Windows Runtime classes and enumerations that a Windows store app can use to communicate with an external USB device that uses WinUSB (Winusb.sys) as the device driver.
, DeviceWatcherEnumerates devices dynamically, so that the app receives notifications if devices are added, removed, or changed after the initial enumeration is complete.
, DataReaderReads data from an input stream. Used for reading data from a USB pipe.
, DataWriterWrites data to an output stream. Used for writing data to a USB pipe.
Operating system requirements
| Client | |
|---|---|
| Server |
Build the sample
Driver requirements
The sample app communicates with the device through the Microsoft-provided kernel-mode driver, Winusb.sys. You must install it as the device driver.
Hardware manufacturers can specify Winusb.sys as the device driver in either of these two ways:
- By providing a custom INF that references the Microsoft-provided Winusb.inf file. For more information, see WinUSB (Winusb.sys) Installation.
- By setting Microsoft operating system (OS) feature descriptors that report the compatible ID as "WINUSB". In this case, Windows matches the compatible ID with the driver and automatically loads Winusb.sys as the device driver. For more information, see WinUSB Device.
- Open Device Manager and locate the device.
- Right-click the device and select Update driver software... from the context menu.
- In the wizard, select Browse my computer for driver software.
- Select Let me pick from a list of device drivers on my computer.
- From the list of device classes, select Universal Serial Bus devices.
- The wizard displays WinUsb Device. Select it to load the driver.
Setting the DeviceInterfaceGUID for the device
If the device appears in Device Manager but the sample cannot detect it, make sure that the DeviceInterfaceGUID is set for this device in one of these ways:
- If you can modify the device firmware, add the WinUSB compatible ID and DeviceInterfaceGUID in the MS OS descriptor. For more information, see Registering a device interface GUID in WinUSB Device. More information is included in this blog post: How to install WinUSB.sys without a custom INF.
- Add the GUID in a custom INF that specifies Winusb.sys as the function driver for the device. Here is an example:
[Dev_AddReg]HKR,,DeviceInterfaceGUIDs,0x10000,"{875d47fc-d331-4663-b339-624001a2dc5e}" - Add the GUID in the registry.
- Load the Wiusb.sys in Device Manager as per the instructions given in the previous section.
- Generate a device interface GUID by using a tool such as guidgen.exe.
- Find the registry key for your USB to Serial Controller device under this key. In this example, VID and PID of the device is VID_056E&PID_5004:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_0564&PID_5004
- Under the Device Parameters key, add a String registry entry named DeviceInterfaceGUID or a Multi-String entry named DeviceInterfaceGUIDs. Set the value to the GUID you generated in step 2.
- Disconnect the device from the system and reconnect it to the same physical port. Apply steps 1 through 4 for each USB to Serial Controller device. Each device has a different device instance. You must add the
DeviceInterfaceGUID entry for each device instance.
Note If you change the physical port then you must repeat steps 1 through 4.
Building the Sample
To build this sample, open the solution (.sln) file titled UsbCdc Control.sln from Microsoft Visual Studio 2013. Press F7 or go to Build->Build Solution from the top menu after the sample has loaded.
Run the sample
- To run this sample after building it, press F5 (run with debugging enabled) or Ctrl-F5 (run without debugging enabled), or select the corresponding options from the Debug menu. To deploy the app, select Build > Deploy UsbCdcControl.
- From the list of detected devices, choose your device and click the Select button.
Note The first time you run the sample, you will be prompted whether you allow the app to use the USB device. Choose Allow to proceed.
If you do not see your device, most likely Winusb.sys was not loaded as the device driver.
If you get an exception, make sure that your app manifest file contains vendor/product Ids of your USB to serial adaptor(s).
- Click the Initialize button. The Output string shows the device as Initialized.
- Choose one of the scenarios in the Select scenario input box: either 2) Read Data or 3) Write Data, and so on.
- To change the serial port parameters, change the values in DTERate,
CharFormat, lists and click Initialize.
- To read data received in Bulk IN endpoint (BulkIn[0]), select 2) Read Data.
Note
This scenario only reads when there is data available to read.
This image shows continuous reading and displays data in binary format. In this case, you do not need to specify the number of bytes to read. When you want to stop reading data, click Stop Continuous Read.
Alternatively, you can specify the number of bytes to read each time you click Read. You can also specify a timeout value. When that value is expires, the read operation completes. The default value is -1 that indicates infinite timeout.
It blocks until completes reading the specified number of bytes are read or until the timeout value is reached.
- To write to the bulk OUT pipe, select 3) Write Data.
There are two ways to write data. The simplest way is to send a text string (specified in the input box) by clicking WriteText as shown in this image. Because the Send NullTerminateChar box is checked, it adds an extra byte to the string. After the write operation is complete, the Output box shows the text and number of bytes written.
Alternatively, you can send contents of a binary file. To do so, click Load Binary Data 1 or Load Binary Data 2and then choose a .bin file from the file picker. Then click Write Binary Data 1 or Write Binary Data 2to start the write operation.
You can also send RS-232C break signal during a specified milliseconds time length by clicking the Send Break.
- To test loop back, you need two USB to RS-232 adapters which are connected with a null-modem cable. Select devices and click
Initialize both devices.
Write text in the input box and click Test Loopback. The string is displayed in the Output box.
If To cancel the loopback test in progress, click
Stop Loopback.